home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / pickup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  27.4 KB  |  995 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)pickup.c    3.1    93/04/11    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*
  6.  *    Contains code for picking objects up, and container use.
  7.  */
  8.  
  9. #include    "hack.h"
  10.  
  11. static void FDECL(unsplitobj, (struct obj *,struct obj *,long));
  12. static void FDECL(simple_look, (struct obj *,BOOLEAN_P));
  13. static boolean FDECL(query_classes, (char *,boolean *,boolean *,
  14.                  const char *,struct obj *,BOOLEAN_P,BOOLEAN_P));
  15. static void FDECL(check_here, (BOOLEAN_P));
  16. static int FDECL(pickup_object, (struct obj *,struct obj *));
  17. static boolean FDECL(mbag_explodes, (struct obj *,int));
  18. STATIC_PTR int FDECL(in_container,(struct obj *));
  19. STATIC_PTR int FDECL(ck_bag,(struct obj *));
  20. STATIC_PTR int FDECL(out_container,(struct obj *));
  21.  
  22. /*
  23.  *  How much the weight of the given container will change when the given
  24.  *  object is removed from it.  This calculation must match the one used
  25.  *  by weight() in mkobj.c.
  26.  */
  27. #define DELTA_CWT(cont,obj)        \
  28.     ((cont)->cursed ? (obj)->owt * 2 :    \
  29.               1 + ((obj)->owt / ((cont)->blessed ? 4 : 2)))
  30.  
  31. static const char moderateloadmsg[] = "You have a little trouble lifting";
  32. static const char nearloadmsg[] = "You have much trouble lifting";
  33.  
  34. static void
  35. unsplitobj(obj_block, obj_chip, resplit)
  36. register struct obj *obj_block, *obj_chip;
  37. long resplit;    /* non-zero => shift the quantities */
  38. {
  39.     if (obj_block->nobj != obj_chip) {
  40.         impossible("can't unsplit objects");
  41.     } else if (resplit) { /* 1st object should be reduced to 'resplit' */
  42.         obj_chip->quan += (obj_block->quan - resplit);
  43.         obj_block->quan = resplit;
  44.         obj_block->owt = weight(obj_block);
  45.         obj_chip->owt = weight(obj_chip);
  46.     } else {  /* 2nd obj should be merged back into 1st, then destroyed */
  47.         obj_block->nobj = obj_chip->nobj;
  48.         obj_block->nexthere = obj_chip->nexthere;
  49.         obj_block->quan += obj_chip->quan;
  50.         obj_block->owt = weight(obj_block);
  51.         /* no need to worry about 'unsplitbill'; unsplit only occurs
  52.            when unable to pick something up, hence we're not dealing
  53.            with billable objects here (I hope!)
  54.          */
  55.         dealloc_obj(obj_chip);
  56.     }
  57. }
  58.  
  59. /* much simpler version of the look-here code; used by query_classes() */
  60. static void
  61. simple_look(otmp, here)
  62. struct obj *otmp;    /* list of objects */
  63. boolean here;        /* flag for type of obj list linkage */
  64. {
  65.     /* Neither of the first two cases is expected to happen, since
  66.      * we're only called after multiple classes of objects have been
  67.      * detected, hence multiple objects must be present.
  68.      */
  69.     if (!otmp) {
  70.         impossible("simple_look(NULL)");
  71.     } else if (!(here ? otmp->nexthere : otmp->nobj)) {
  72.         pline("%s", doname(otmp));
  73.     } else {
  74.         winid tmpwin = create_nhwindow(NHW_MENU);
  75.         putstr(tmpwin, 0, "");
  76.         do {
  77.         putstr(tmpwin, 0, doname(otmp));
  78.         otmp = here ? otmp->nexthere : otmp->nobj;
  79.         } while (otmp);
  80.         display_nhwindow(tmpwin, TRUE);
  81.         destroy_nhwindow(tmpwin);
  82.     }
  83. }
  84.  
  85. int
  86. collect_obj_classes(ilets, otmp, here, incl_gold)
  87. char ilets[];
  88. register struct obj *otmp;
  89. boolean here, incl_gold;
  90. {
  91.     register int iletct = 0;
  92.     register char c, last_c = '\0';
  93.  
  94.     if (incl_gold)
  95.         ilets[iletct++] = def_oc_syms[GOLD_CLASS];
  96.     ilets[iletct] = '\0'; /* terminate ilets so that index() will work */
  97.     while (otmp) {
  98.         c = def_oc_syms[(int)otmp->oclass];
  99.         if (c != last_c && !index(ilets, (last_c = c)))
  100.             ilets[iletct++] = c,  ilets[iletct] = '\0';
  101.         otmp = here ? otmp->nexthere : otmp->nobj;
  102.     }
  103.  
  104.     return iletct;
  105. }
  106.  
  107. static boolean
  108. query_classes(oclasses, one_at_a_time, everything, action, objs, here, incl_gold)
  109. char oclasses[];
  110. boolean *one_at_a_time, *everything;
  111. const char *action;
  112. struct obj *objs;
  113. boolean here, incl_gold;
  114. {
  115.     char ilets[20], inbuf[BUFSZ];
  116.     int iletct, oclassct;
  117.     char qbuf[QBUFSZ];
  118.  
  119.     oclasses[oclassct = 0] = '\0';
  120.     *one_at_a_time = *everything = FALSE;
  121.     iletct = collect_obj_classes(ilets, objs, here, incl_gold);
  122.     if (iletct == 0) {
  123.         return FALSE;
  124.     } else if (iletct == 1) {
  125.         oclasses[0] = def_char_to_objclass(ilets[0]);
  126.         oclasses[1] = '\0';
  127.     } else  {    /* more than one choice available */
  128.         const char *where = 0;
  129.         register char sym, oc_of_sym, *p;
  130.         /* additional choices */
  131.         ilets[iletct++] = ' ';
  132.         ilets[iletct++] = 'a';
  133.         ilets[iletct++] = 'A';
  134.         ilets[iletct++] = (objs == invent ? 'i' : ':');
  135.         ilets[iletct] = '\0';
  136. ask_again:
  137.         oclasses[oclassct = 0] = '\0';
  138.         *one_at_a_time = *everything = FALSE;
  139.         Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",
  140.             action, ilets);
  141.         getlin(qbuf,inbuf);
  142.         if (*inbuf == '\033') return FALSE;
  143.  
  144.         for (p = inbuf; (sym = *p++); ) {
  145.             /* new A function (selective all) added by GAN 01/09/87 */
  146.             if (sym == ' ') continue;
  147.             else if (sym == 'A') *one_at_a_time = TRUE;
  148.             else if (sym == 'a') *everything = TRUE;
  149.             else if (sym == ':') {
  150.             simple_look(objs, here);  /* dumb if objs==invent */
  151.             goto ask_again;
  152.             } else if (sym == 'i') {
  153.             (void) display_inventory(NULL, FALSE);
  154.             goto ask_again;
  155.             } else {
  156.             oc_of_sym = def_char_to_objclass(sym);
  157.             if (index(ilets,sym)) {
  158.                 oclasses[oclassct++] = oc_of_sym;
  159.                 oclasses[oclassct] = '\0';
  160.             } else {
  161.                 if (!where)
  162.                 where = !strcmp(action,"pick up")  ? "here" :
  163.                     !strcmp(action,"take out") ?
  164.                                 "inside" : "";
  165.                 if (*where)
  166.                 pline("There are no %c's %s.", sym, where);
  167.                 else
  168.                 You("have no %c's.", sym);
  169.             }
  170.             }
  171.         }
  172.         if (!oclassct && !*everything) *one_at_a_time = TRUE;
  173.     }
  174.     return TRUE;
  175. }
  176.  
  177. /* look at the objects at our location, unless there are too many of them */
  178. static void
  179. check_here(picked_some)
  180. boolean picked_some;
  181. {
  182.     register struct obj *obj;
  183.     register int ct = 0;
  184.  
  185.     /* count the objects here */
  186.     for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) {
  187.         if (obj != uchain)
  188.         ct++;
  189.     }
  190.  
  191.     /* If there are objects here, take a look. */
  192.     if (ct) {
  193.         if (flags.run) nomul(0);
  194.         flush_screen(1);
  195.         if (ct < 5) {
  196.         (void) dolook();
  197.         } else {
  198.         read_engr_at(u.ux,u.uy);
  199.         pline("There are several %sobjects here.",
  200.               picked_some ? "more " : "");
  201.         }
  202.     } else {
  203.         read_engr_at(u.ux,u.uy);
  204.     }
  205. }
  206.  
  207. void
  208. pickup(all)
  209. int all;    /* all >= 0 => yes/no; < 0 => -count */
  210. {
  211.     register struct obj *obj;
  212.     struct obj *obj2, *objx;
  213.     boolean all_of_a_type, selective;
  214.     char oclasses[20];
  215.     long count;
  216.     int pick, pick_count = 0;
  217.  
  218.     count = (all < 0) ? (-1L * all) : 0L;
  219.     if (count) all = 0;
  220.  
  221.     if (all && (flags.nopick || !OBJ_AT(u.ux, u.uy) ||
  222.             (is_pool(u.ux, u.uy) && !Underwater))) {
  223.         read_engr_at(u.ux, u.uy);
  224.         return;
  225.     }
  226.  
  227.     if (Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
  228.         if ((multi && !flags.run) || (all && !flags.pickup))
  229.             read_engr_at(u.ux,u.uy);
  230.         return;
  231.     }
  232.  
  233.     /* multi && !flags.run means they are in the middle of some other
  234.      * action, or possibly paralyzed, sleeping, etc.... and they just
  235.      * teleported onto the object.  They shouldn't pick it up.
  236.      */
  237.     if ((multi && !flags.run) || (all && !flags.pickup)) {
  238.         check_here(FALSE);
  239.         return;
  240.     }
  241.  
  242.     oclasses[0] = '\0';    /* types to consider (empty for all) */
  243.     all_of_a_type = TRUE;    /* take all of considered types */
  244.     selective = FALSE;    /* ask for each item */
  245.  
  246.     if (all) {
  247.         if (flags.pickup) Strcpy(oclasses, flags.pickup_types);
  248.     } else {
  249.         /* check for more than one object */
  250.         register int ct = 0;
  251.  
  252.         for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
  253.             ct++;
  254.  
  255.         if (ct >= 2) {
  256.             pline("There are several objects here.");
  257.             count = 0;
  258.  
  259.             /* added by GAN 10/24/86 to allow selective picking up */
  260.             if (!query_classes(oclasses, &selective, &all_of_a_type,
  261.               "pick up", level.objects[u.ux][u.uy], TRUE, FALSE))
  262.             return;
  263.         }
  264.     }
  265.  
  266.     for (obj = level.objects[u.ux][u.uy]; obj; obj = obj2) {
  267.         obj2 = obj->nexthere;    /* perhaps obj will be picked up */
  268.         objx = 0;
  269.         if (flags.run) nomul(0);
  270.  
  271.         if (!selective && oclasses[0] && !index(oclasses,obj->oclass))
  272.             continue;
  273.  
  274.         if (!all_of_a_type) {
  275.             char qbuf[QBUFSZ];
  276.             Sprintf(qbuf, "Pick up %s?", doname(obj));
  277.             switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) {
  278.             case 'q': return;
  279.             case 'n': continue;
  280.             case 'a':
  281.             all_of_a_type = TRUE;
  282.             if (selective) {
  283.                 selective = FALSE;
  284.                 oclasses[0] = obj->oclass;
  285.                 oclasses[1] = '\0';
  286.             }
  287.             break;
  288.             case '#':    /* count was entered */
  289.             if (!yn_number) continue; /* 0 count => No */
  290.             else count = yn_number;
  291.             /* fall thru */
  292.             default:    /* 'y' */
  293.             break;
  294.             }
  295.         }
  296.  
  297.         if (count) {
  298.             /* Pickup a specific number of items; split the object
  299.                unless count corresponds to full quantity.  1 special
  300.                case:  cursed loadstones will remain as merged unit.
  301.              */
  302.             if (count < obj->quan &&
  303.                 (!obj->cursed || obj->otyp != LOADSTONE)) {
  304.             objx = splitobj(obj, count);
  305.             if (!objx || objx->nexthere != obj2)
  306.                 impossible("bad object split in pickup");
  307.             }
  308.             count = 0;    /* reset */
  309.         }
  310.         if ((pick = pickup_object(obj, objx)) < 0) break;
  311.         pick_count += pick;
  312.     }
  313.  
  314.     /*
  315.      *  Re-map what is at the hero's location after the pickup so the
  316.      *  map is correct.
  317.      */
  318.     newsym(u.ux,u.uy);
  319.  
  320.     /* see whether there's anything else here, after auto-pickup is done */
  321.     if (all && flags.pickup) check_here(pick_count > 0);
  322. }
  323.  
  324. /*
  325.  * Pick up an object from the ground or out of a container and add it to
  326.  * the inventory.  Returns -1 if pickup() should break out of its loop,
  327.  * 0 if nothing picked up, 1 if otherwise.
  328.  */
  329. static int
  330. pickup_object(obj, objx)
  331. struct obj *obj, *objx;
  332. {
  333.     int wt, nearload;
  334.     long pickquan;
  335.  
  336.     /* in case of auto-pickup, where we haven't had a chance
  337.        to look at it yet; affects docall(SCR_SCARE_MONSTER) */
  338.     if (!Blind) obj->dknown = 1;
  339.  
  340.     if (obj == uchain) {    /* do not pick up attached chain */
  341.         return 0;
  342.     } else if (obj->oartifact && !touch_artifact(obj,&youmonst)) {
  343.         return 0;
  344.     } else if (obj->otyp == GOLD_PIECE) {
  345.         /*
  346.          *  Special consideration for gold pieces...
  347.          */
  348.         long iw = (long)max_capacity() - ((u.ugold + 50L) / 100L);
  349.         long gold_capacity = ((-iw) * 100L) - 50L + 99L - u.ugold;
  350.  
  351.         if (gold_capacity <= 0L) {
  352.         if (objx) unsplitobj(obj, objx, 0L);
  353.        pline("There %s %ld gold piece%s here, but you cannot carry any more.",
  354.             (obj->quan == 1L) ? "is" : "are",
  355.             obj->quan, plur(obj->quan));
  356.         return 0;
  357.         } else if (gold_capacity < obj->quan) {
  358.         if (objx) unsplitobj(obj, objx, 0L);
  359.         You("can only carry %s of the %ld gold pieces lying here.",
  360.             gold_capacity == 1L ? "one" : "some", obj->quan);
  361.         pline("%s %ld gold piece%s.",
  362.             nearloadmsg, gold_capacity, plur(gold_capacity));
  363.         u.ugold += gold_capacity;
  364.         obj->quan -= gold_capacity;
  365.         costly_gold(obj->ox, obj->oy, gold_capacity);
  366.         } else {
  367.         u.ugold += obj->quan;
  368.         if ((nearload = near_capacity()) != 0)
  369.             pline("%s %ld gold piece%s.",
  370.               nearload < MOD_ENCUMBER ?
  371.               moderateloadmsg : nearloadmsg,
  372.               obj->quan, plur(obj->quan));
  373.         else
  374.             prinv(NULL, obj, 0L);
  375.         costly_gold(obj->ox, obj->oy, obj->quan);
  376.         delobj(obj);
  377.         }
  378.         flags.botl = 1;
  379.         if (flags.run) nomul(0);
  380.         return 1;
  381.     } else if (obj->otyp == CORPSE) {
  382.  
  383.         if (obj->corpsenm == PM_COCKATRICE && !uarmg
  384. #ifdef POLYSELF
  385.         && !resists_ston(uasmon)
  386. #endif
  387.         ) {
  388. #ifdef POLYSELF
  389.         if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
  390.             display_nhwindow(WIN_MESSAGE, FALSE);
  391.         else
  392. #endif
  393.         {
  394.           pline("Touching the cockatrice corpse is a fatal mistake.");
  395.             You("turn to stone.");
  396.             You("die...");
  397.             killer_format = KILLED_BY_AN;
  398.             killer = "cockatrice corpse";
  399.             done(STONING);
  400.             return -1;
  401.         }
  402.         } else if (is_rider(&mons[obj->corpsenm])) {
  403.         pline("At your touch, the corpse suddenly moves...");
  404.         revive_corpse(obj, 1, FALSE);
  405.         exercise(A_WIS, FALSE);
  406.         return -1;
  407.         }
  408.     } else  if (obj->otyp == SCR_SCARE_MONSTER) {
  409.         if (obj->blessed) obj->blessed = 0;
  410.         else if (!obj->spe && !obj->cursed) obj->spe = 1;
  411.         else {
  412.         pline("The scroll%s turn%s to dust as you pick %s up.",
  413.             plur(obj->quan), (obj->quan == 1L) ? "s" : "",
  414.             (obj->quan == 1L) ? "it" : "them");
  415.         if (!(objects[SCR_SCARE_MONSTER].oc_name_known) &&
  416.                     !(objects[SCR_SCARE_MONSTER].oc_uname))
  417.             docall(obj);
  418.         useupf(obj);
  419.         return 1;    /* tried to pick something up and failed, but
  420.                    don't want to terminate pickup loop yet   */
  421.         }
  422.     }
  423.  
  424.     wt = max_capacity() + (int)obj->owt;
  425.     if (obj->otyp == LOADSTONE)
  426.         goto lift_some;     /* pick it up even if too heavy */
  427. #ifdef POLYSELF
  428.     if (obj->otyp == BOULDER && throws_rocks(uasmon)) {
  429.         goto lift_some;
  430.     }
  431. #endif
  432.     if (wt > 0) {
  433.         if (obj->quan > 1L) {
  434.         /* see how many we can lift */
  435.         long qq, savequan = obj->quan;
  436.         int iw = max_capacity();
  437.         /*  This is correct only because containers */
  438.         /*  don't merge.    -dean            */
  439.         for (qq = 1; qq < savequan; qq++) {
  440.             obj->quan = qq;
  441.             if (iw + weight(obj) > 0)
  442.                 break;
  443.         }
  444.         obj->quan = savequan;
  445.         qq--;
  446.         /* we can carry qq of them */
  447.         if (qq) {
  448.             if (objx) {        /* temporarily unsplit */
  449.             savequan = obj->quan;
  450.             obj->quan += objx->quan;
  451.             }
  452.             You("can only carry %s of the %s lying here.",
  453.             (qq == 1L) ? "one" : "some", doname(obj));
  454.             if (objx) {        /* re-do the prior split */
  455.             obj->quan = savequan;
  456.             unsplitobj(obj, objx, qq);
  457.             } else {        /* split into two groups */
  458.             objx = splitobj(obj, qq);
  459.             if (objx->otyp == SCR_SCARE_MONSTER) objx->spe = 0;
  460.             }
  461.             goto lift_some;
  462.         }
  463.         }
  464.         if (objx) unsplitobj(obj, objx, 0L);
  465.         pline("There %s %s here, but %s.",
  466.             (obj->quan == 1L) ? "is" : "are", doname(obj),
  467.             !invent ? (obj->quan == 1L ?
  468.                 "it is too heavy for you to lift" :
  469.                 "they are too heavy for you to lift") :
  470.             "you cannot carry any more");
  471.         if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0;
  472.         return -1;
  473.     }
  474.  
  475. lift_some:
  476.     if (inv_cnt() >= 52) {
  477.         if (objx) unsplitobj(obj, objx, 0L);
  478.         if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0;
  479.         Your("knapsack cannot accommodate any more items.");
  480.         return -1;
  481.     }
  482.  
  483.     if (obj->otyp != LOADSTONE &&
  484.         (wt*2 / weight_cap()) + 1 > SLT_ENCUMBER) {
  485.         /* as in near_capacity() */
  486.         char qbuf[QBUFSZ];
  487.         char ch;
  488.  
  489.         Sprintf(qbuf, "%s %s.  Continue?", nearloadmsg, doname(obj));
  490.         switch (ch = ynq(qbuf)) {
  491.             case 'n':
  492.             case 'q':
  493.                 if (objx) unsplitobj(obj, objx, 0L);
  494.                 if (obj->otyp == SCR_SCARE_MONSTER)
  495.                     obj->spe = 0;
  496.                 return (ch == 'q') ? -1 : 0;
  497.             default:  break;    /* 'y' */
  498.         }
  499.     }
  500.  
  501.     pickquan = obj->quan;    /* save number picked up */
  502.     obj = pick_obj(obj);
  503.  
  504.     if (uwep && uwep == obj) mrg_to_wielded = TRUE;
  505.     nearload = near_capacity();
  506.     prinv(nearload == SLT_ENCUMBER ? moderateloadmsg : NULL,
  507.         obj, pickquan);
  508.     mrg_to_wielded = FALSE;
  509.     return 1;
  510. }
  511.  
  512. /* Gold never reaches this routine. */
  513. struct obj *
  514. pick_obj(otmp)
  515. register struct obj *otmp;
  516. {
  517.     freeobj(otmp);
  518.     if (*u.ushops && costly_spot(u.ux, u.uy) &&
  519.         otmp != uball)     /* don't charge for this - kd, 1/17/90 */
  520.        /* sets obj->unpaid if necessary */
  521.         addtobill(otmp, TRUE, FALSE, FALSE);
  522.     if(Invisible) newsym(u.ux,u.uy);
  523.     return(addinv(otmp));    /* might merge it with other objects */
  524. }
  525.  
  526. /*
  527.  * prints a message if encumbrance changed since the last check and
  528.  * returns the new encumbrance value (from near_capacity()).
  529.  */
  530. int
  531. encumber_msg()
  532. {
  533.     static int oldcap = UNENCUMBERED;
  534.     int newcap = near_capacity();
  535.  
  536.     if(oldcap < newcap) {
  537.     switch(newcap) {
  538.     case 1: Your("movements are slowed slightly because of your load.");
  539.         break;
  540.     case 2: You("rebalance your load.  Movement is difficult.");
  541.         break;
  542.     case 3: You("stagger under your heavy load.  Movement is very hard.");
  543.         break;
  544.     default: You("can barely move a handspan with this load!");
  545.         break;
  546.     }
  547.     flags.botl = 1;
  548.     } else if(oldcap > newcap) {
  549.     switch(newcap) {
  550.     case 0: Your("movements are now unencumbered.");
  551.         break;
  552.     case 1: Your("movements are only slowed slightly by your load.");
  553.         break;
  554.     case 2: You("rebalance your load.  Movement is still difficult.");
  555.         break;
  556.     case 3: You("stagger under your load.  Movement is still very hard.");
  557.         break;
  558.     }
  559.     flags.botl = 1;
  560.     }
  561.  
  562.     oldcap = newcap;
  563.     return (newcap);
  564. }
  565.  
  566. int
  567. doloot()    /* loot a container on the floor. */
  568. {
  569.     register struct obj *cobj, *nobj;
  570.     register int c;
  571.     int timepassed = 0;
  572.  
  573.     if (Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
  574.         You("cannot reach the floor.");
  575.         return(0);
  576.     }
  577.     if(is_pool(u.ux, u.uy)) {
  578.         You("cannot loot things that are deep in the water.");
  579.         return(0);
  580.     }
  581.  
  582. #ifdef POLYSELF
  583.     if(nolimbs(uasmon)) {
  584.         You("cannot loot things without limbs.");
  585.         return(0);
  586.     }
  587. #endif
  588.  
  589.     for(cobj = level.objects[u.ux][u.uy]; cobj; cobj = nobj) {
  590.         nobj = cobj->nexthere;
  591.  
  592.         if(Is_container(cobj)) {
  593.             char qbuf[QBUFSZ];
  594.  
  595.             Sprintf(qbuf, "There is %s here, loot it?", doname(cobj));
  596.             c = ynq(qbuf);
  597.             if(c == 'q') return (timepassed);
  598.             if(c == 'n') continue;
  599.  
  600.             if(cobj->olocked) {
  601.             pline("Hmmm, it seems to be locked.");
  602.             continue;
  603.             }
  604.             if(cobj->otyp == BAG_OF_TRICKS) {
  605.             You("carefully open the bag...");
  606.             pline("It develops a huge set of teeth and bites you!");
  607.             c = rnd(10);
  608.             if(Half_physical_damage) c = (c+1) / 2;
  609.             losehp(c, "carnivorous bag", KILLED_BY_AN);
  610.             makeknown(BAG_OF_TRICKS);
  611.             timepassed = 1;
  612.             continue;
  613.             }
  614.  
  615.             You("carefully open %s...", the(xname(cobj)));
  616.             if (cobj->otrapped && chest_trap(cobj, FINGER, FALSE)) {
  617.             timepassed = 1;
  618.             continue;    /* explosion destroyed cobj */
  619.             }
  620.             if(multi < 0) return (1); /* a paralysis trap */
  621.  
  622.             timepassed |= use_container(cobj, 0);
  623.         }
  624.     }
  625.     return (timepassed);
  626. }
  627.  
  628. /*
  629.  * Decide whether an object being placed into a magic bag will cause
  630.  * it to explode.  If the object is a bag itself, check recursively.
  631.  */
  632. static boolean
  633. mbag_explodes(obj, depthin)
  634.     struct obj *obj;
  635.     int depthin;
  636. {
  637.     /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */
  638.     if ((Is_mbag(obj) || (obj->otyp == WAN_CANCELLATION && obj->spe > 0)) &&
  639.     (rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin))
  640.     return TRUE;
  641.     else if (Has_contents(obj)) {
  642.     struct obj *otmp;
  643.  
  644.     for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
  645.         if (mbag_explodes(otmp, depthin+1)) return TRUE;
  646.     }
  647.     return FALSE;
  648. }
  649.  
  650. /* A variable set in use_container(), to be used by the callback routines */
  651. /* chk_bg(), in_container(), and out_container() from askchain().      */
  652. static NEARDATA struct obj *current_container;
  653. #define Icebox (current_container->otyp == ICE_BOX)
  654.  
  655. STATIC_PTR int
  656. in_container(obj)
  657. register struct obj *obj;
  658. {
  659.     register struct obj *gold;
  660.     boolean is_gold = (obj->otyp == GOLD_PIECE);
  661.     boolean floor_container = !carried(current_container);
  662.     char buf[BUFSZ];
  663.  
  664.     if (!current_container) {
  665.         impossible("<in> no current_container?");
  666.         return 0;
  667.     } else if (obj == uball || obj == uchain) {
  668.         You("must be kidding.");
  669.         return 0;
  670.     } else if (obj == current_container) {
  671.         pline("That would be an interesting topological exercise.");
  672.         return 0;
  673.     } else if (obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) {
  674.         Norep("You cannot %s something you are wearing.",
  675.             Icebox ? "refrigerate" : "stash");
  676.         return 0;
  677.     } else if ((obj->otyp == LOADSTONE) && obj->cursed) {
  678.         obj->bknown = 1;
  679.           pline("The stone%s won't leave your person.", plur(obj->quan));
  680.         return 0;
  681.     } else if (obj->otyp == AMULET_OF_YENDOR ||
  682.            obj->otyp == CANDELABRUM_OF_INVOCATION ||
  683.            obj->otyp == BELL_OF_OPENING ||
  684.            obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  685.     /* Prohibit Amulets in containers; if you allow it, monsters can't
  686.      * steal them.  It also becomes a pain to check to see if someone
  687.      * has the Amulet.  Ditto for the Candelabrum, the Bell and the Book.
  688.      */
  689.         pline("%s cannot be confined in such trappings.", The(xname(obj)));
  690.         return 0;
  691.     }
  692. #ifdef WALKIES
  693.     else if (obj->otyp == LEASH && obj->leashmon != 0) {
  694.         pline("%s is attached to your pet.", The(xname(obj)));
  695.         return 0;
  696.     }
  697. #endif
  698.     else if (obj == uwep) {
  699.         if (welded(obj)) {
  700.             weldmsg(obj, FALSE);
  701.             return 0;
  702.         }
  703.         setuwep((struct obj *) 0);
  704.         if (uwep) return 0;    /* unwielded, died, rewielded */
  705.     }
  706.  
  707.     /* boxes can't fit into any container */
  708.     if (obj->otyp == ICE_BOX || Is_box(obj)) {
  709.         /*
  710.          *  xname() uses a static result array.  Save obj's name
  711.          *  before current_container's name is computed.  Don't
  712.          *  use the result of strcpy() within You() --- the order
  713.          *  of evaluation of the parameters is undefined.
  714.          */
  715.         Strcpy(buf, the(xname(obj)));
  716.         You("cannot fit %s into %s.", buf,
  717.             the(xname(current_container)));
  718.         return 0;
  719.     }
  720.  
  721.     freeinv(obj);
  722.  
  723.     if (is_gold) {    /* look for other gold within the container */
  724.         for (gold = current_container->cobj; gold; gold = gold->nobj)
  725.             if (gold->otyp == GOLD_PIECE) break;
  726.     } else
  727.         gold = 0;
  728.  
  729.     if (gold) {
  730.         gold->quan += obj->quan;
  731.     } else {
  732.         obj->nobj = current_container->cobj;
  733.         current_container->cobj = obj;
  734.     }
  735.  
  736.     current_container->owt = weight(current_container);
  737.  
  738.     Strcpy(buf, the(xname(current_container)));
  739.     You("put %s into %s.", doname(obj), buf);
  740.  
  741.     if (floor_container && costly_spot(u.ux, u.uy)) {
  742.         sellobj_state(TRUE);
  743.         sellobj(obj, u.ux, u.uy);
  744.         sellobj_state(FALSE);
  745.     }
  746.     (void) snuff_candle(obj); /* must follow the "put" msg */
  747.     if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN
  748.             && !Is_candle(obj))
  749.         obj->age = monstermoves - obj->age; /* actual age */
  750.  
  751.     else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) {
  752.         You("are blasted by a magical explosion!");
  753.  
  754.         /* the !floor_container case is taken care of */
  755.         if(*u.ushops && costly_spot(u.ux, u.uy) && floor_container) {
  756.             register struct monst *shkp;
  757.  
  758.             if ((shkp = shop_keeper(*u.ushops)) != 0)
  759.             (void)stolen_value(current_container, u.ux, u.uy,
  760.                        (boolean)shkp->mpeaceful, FALSE);
  761.         }
  762.         delete_contents(current_container);
  763.         if (!floor_container)
  764.             useup(current_container);
  765.         else if (obj_here(current_container, u.ux, u.uy))
  766.             useupf(current_container);
  767.         else
  768.             panic("in_container:  bag not found.");
  769.  
  770.         losehp(d(6,6),"magical explosion", KILLED_BY_AN);
  771.         current_container = 0;    /* baggone = TRUE; */
  772.     }
  773.  
  774.     if (is_gold) {
  775.         if (gold) dealloc_obj(obj);
  776.         bot();    /* update character's gold piece count immediately */
  777.     }
  778.  
  779.     return(current_container ? 1 : -1);
  780. }
  781.  
  782. STATIC_PTR int
  783. ck_bag(obj)
  784. struct obj *obj;
  785. {
  786.     return current_container && obj != current_container;
  787. }
  788.  
  789. STATIC_PTR int
  790. out_container(obj)
  791. register struct obj *obj;
  792. {
  793.     register struct obj *otmp, *ootmp;
  794.     boolean is_gold = (obj->otyp == GOLD_PIECE);
  795.     int loadlev;
  796.     long quan;
  797.  
  798.     if (!current_container) {
  799.         impossible("<out> no current_container?");
  800.         return -1;
  801.     } else if (is_gold) {
  802.         obj->owt = weight(obj);
  803.     } else if (inv_cnt() >= 52) {
  804.         You("have no room to hold anything else.");
  805.         return -1;    /* skips gold too; oh well */
  806.     }
  807.  
  808.     if(obj->oartifact && !touch_artifact(obj,&youmonst)) return 0;
  809.  
  810.     if(obj->otyp != LOADSTONE && max_capacity() + (int)obj->owt -
  811.        (carried(current_container) ?
  812.         (current_container->otyp == BAG_OF_HOLDING ?
  813.          (int)DELTA_CWT(current_container,obj) : (int)obj->owt) : 0) > 0) {
  814.         char buf[BUFSZ];
  815.  
  816.         Strcpy(buf, doname(obj));
  817.         pline("There %s %s in %s, but %s.",
  818.             obj->quan==1 ? "is" : "are",
  819.             buf, the(xname(current_container)),
  820.             invent ? "you cannot carry any more"
  821.             : "it is too heavy for you to carry");
  822.         /* "too heavy for you to lift" is not right if you're carrying
  823.            the container... */
  824.         return(0);
  825.     }
  826.     /* Remove the object from the list. */
  827.     if (obj == current_container->cobj)
  828.         current_container->cobj = obj->nobj;
  829.     else {
  830.         for(otmp = current_container->cobj; otmp->nobj != obj;
  831.                                 otmp = otmp->nobj)
  832.             if(!otmp->nobj) panic("out_container");
  833.         otmp->nobj = obj->nobj;
  834.     }
  835.  
  836.     current_container->owt = weight(current_container);
  837.  
  838.     if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN
  839.             && !Is_candle(obj))
  840.         obj->age = monstermoves - obj->age;
  841.     /* simulated point of time */
  842.  
  843.     if(!obj->unpaid && !carried(current_container) &&
  844.          costly_spot(current_container->ox, current_container->oy)) {
  845.  
  846.         obj->ox = current_container->ox;
  847.         obj->oy = current_container->oy;
  848.         addtobill(obj, FALSE, FALSE, FALSE);
  849.     }
  850.  
  851.     quan = obj->quan;
  852.     ootmp = addinv(obj);
  853.     loadlev = near_capacity();
  854.     prinv(loadlev ?
  855.           (loadlev < MOD_ENCUMBER ?
  856.            "You have a little trouble removing" :
  857.            "You have much trouble removing") : NULL,
  858.           ootmp, quan);
  859.  
  860.     if (is_gold) {
  861.         dealloc_obj(obj);
  862.         bot();    /* update character's gold piece count immediately */
  863.     }
  864.     return 1;
  865. }
  866.  
  867. /* for getobj: allow counts, allow all types, expect food */
  868. static NEARDATA const char frozen_food[] =
  869.     { ALLOW_COUNT, ALL_CLASSES, FOOD_CLASS, 0 };
  870.  
  871. int
  872. use_container(obj, held)
  873. register struct obj *obj;
  874. register int held;
  875. {
  876.     register int cnt = 0;
  877.     register struct obj *curr, *prev, *otmp;
  878.     boolean one_by_one, allflag;
  879.     char select[MAXOCLASSES+1];
  880.     char qbuf[QBUFSZ];
  881.     int used = 0, lcnt = 0;
  882.     long loss = 0L;
  883.     register struct monst *shkp;
  884.  
  885.     current_container = obj;    /* for use by in/out_container */
  886.     if (current_container->olocked) {
  887.         pline("%s seems to be locked.", The(xname(current_container)));
  888.         if (held) You("must put it down to unlock.");
  889.         return 0;
  890.     }
  891.     /* Count the number of contained objects. Sometimes toss objects if */
  892.     /* a cursed magic bag.                            */
  893.     prev = (struct obj *) 0;
  894.     for (curr = obj->cobj; curr; curr = otmp) {
  895.         otmp = curr->nobj;
  896.         if (Is_mbag(obj) && obj->cursed && !rn2(13)) {
  897.         if (curr->known)
  898.             pline("%s to have vanished!", The(aobjnam(curr,"seem")));
  899.         else
  900.             You("%s %s disappear.", Blind ? "notice" : "see",
  901.                             doname(curr));
  902.         if (prev)
  903.             prev->nobj = otmp;
  904.         else
  905.             obj->cobj = otmp;
  906.  
  907.         if(*u.ushops && (shkp = shop_keeper(*u.ushops))) {
  908.             if(held) {
  909.             if(curr->unpaid)
  910.                 loss += stolen_value(curr, u.ux, u.uy,
  911.                          (boolean)shkp->mpeaceful, TRUE);
  912.             lcnt++;
  913.             } else if(costly_spot(u.ux, u.uy)) {
  914.             loss += stolen_value(curr, u.ux, u.uy,
  915.                          (boolean)shkp->mpeaceful, TRUE);
  916.             lcnt++;
  917.             }
  918.         }
  919.         /* obfree() will free all contained objects */
  920.         obfree(curr, (struct obj *) 0);
  921.         } else {
  922.         prev = curr;
  923.         cnt++;
  924.         }
  925.     }
  926.  
  927.     if (cnt && loss)
  928.         You("owe %ld zorkmids for lost item%s.",
  929.         loss, lcnt > 1 ? "s" : "");
  930.  
  931.     current_container->owt = weight(current_container);
  932.  
  933.     if(!cnt)
  934.         pline("%s %s is empty.", (held) ? "Your" : "The", xname(obj));
  935.     else {
  936.         Sprintf(qbuf, "Do you want to take something out of %s?",
  937.             the(xname(obj)));
  938. ask_again:
  939.         switch (yn_function(qbuf, ":ynq", 'n')) {
  940.         case ':':
  941.         container_contents(current_container, FALSE, FALSE);
  942.         goto ask_again;
  943.         case 'y':
  944.         if (query_classes(select, &one_by_one, &allflag, "take out",
  945.                    current_container->cobj, FALSE, FALSE)) {
  946.             if (askchain((struct obj **)¤t_container->cobj,
  947.                  (one_by_one ? (char *)0 : select), allflag,
  948.                  out_container, (int (*)())0, 0, "nodot"))
  949.             used = 1;
  950.         }
  951.         /*FALLTHRU*/
  952.         case 'n':
  953.         break;
  954.         case 'q':
  955.         default:
  956.         return 0;
  957.         }
  958.     }
  959.  
  960.     if (!invent && (u.ugold == 0 || Icebox)) return used;
  961.     if (yn_function("Do you wish to put something in?", ynqchars, 'n')
  962.         != 'y') return used;
  963.     if (Icebox && current_container->dknown) {
  964.         otmp = getobj(frozen_food, "put in");
  965.         if(!otmp || !in_container(otmp))
  966.             flags.move = multi = 0;
  967.     } else {
  968.         if (query_classes(select, &one_by_one, &allflag, "put in",
  969.                        invent, FALSE, (u.ugold != 0L))) {
  970.             struct obj *u_gold = (struct obj *)0;
  971.             if (u.ugold && (one_by_one || (allflag && !*select)
  972.                     || index(select, GOLD_CLASS))) {
  973.             /* make gold object & insert at head of inventory */
  974.             u_gold = mkgoldobj(u.ugold);    /*(removes gold too)*/
  975.             u.ugold = u_gold->quan;        /* put the gold back */
  976.             u_gold->nobj = invent;
  977.             invent = u_gold;
  978.             }
  979.             used = (askchain((struct obj **)&invent,
  980.                 (one_by_one ? (char *)0 : select), allflag,
  981.                 in_container, ck_bag, 0, "nodot") > 0);
  982.             if (u_gold && invent && invent->otyp == GOLD_PIECE) {
  983.             /* didn't stash [all of] it */
  984.             u_gold = invent;
  985.             invent = u_gold->nobj;
  986.             dealloc_obj(u_gold);
  987.             }
  988.         }
  989.     }
  990.  
  991.     return used;
  992. }
  993.  
  994. /*pickup.c*/
  995.